/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace DaveSexton.DocProject
{
	public sealed partial class DocProjectPropertiesControl : UserControl
	{
		#region Public Properties
		public IDocProject Project
		{
			get
			{
				return project;
			}
			set
			{
				if (value == null)
					throw new ArgumentNullException("value");
				else if (options != null)
					serviceContainer.Remove(options);

				project = value;

				if (project == null)
					options = null;
				else
				{
					options = project.Options;

					// required so that options can find services such as IComponentChangeService
					serviceContainer.Add(options);
				}

				grid.SelectedObject = options;
			}
		}
		#endregion

		#region Private / Protected
		private IDocProject project;
		private DocProjectOptions options;
		private readonly Container serviceContainer = new ServiceContainer();
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="DocProjectPropertiesControl" /> class.
		/// </summary>
		public DocProjectPropertiesControl()
		{
			InitializeComponent();

			DocProjectEnvironment.ProjectSaved += DocProjectEnvironment_ProjectSaved;
		}
		#endregion

		#region Methods
		private void SynchronizeResetItem(GridItem item)
		{
			bool canReset = false;

			if (item != null && item.GridItemType == GridItemType.Property)
			{
				GridItem parent = item.Parent;

				object obj = null;

				if (parent.GridItemType == GridItemType.Category || parent.GridItemType == GridItemType.Root)
					obj = grid.SelectedObject;
				else if (parent.GridItemType == GridItemType.Property)
					obj = parent.Value;

				canReset = obj != null && item.PropertyDescriptor.CanResetValue(obj)
					&& item.PropertyDescriptor.ShouldSerializeValue(obj);
			}

			resetToolStripMenuItem.Enabled = canReset;
		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			if (disposing)
			{
				if (components != null)
					components.Dispose();

				serviceContainer.Dispose();
			}
			base.Dispose(disposing);
		}
		#endregion

		#region Event Handlers
		private void DocProjectEnvironment_ProjectSaved(object sender, DocProjectEventArgs e)
		{
			if (project != null && project.Matches(e.Project))
				grid.Refresh();
		}

		protected override void OnLoad(EventArgs e)
		{
			if (Site == null || !Site.DesignMode)
				// required so that the grid can find services such as IComponentChangeService
				serviceContainer.Add(grid);

			base.OnLoad(e);
		}

		private void grid_SelectedGridItemChanged(object sender, SelectedGridItemChangedEventArgs e)
		{
			SynchronizeResetItem(e.NewSelection);
		}

		private void grid_PropertyValueChanged(object s, PropertyValueChangedEventArgs e)
		{
			GridItem item = e.ChangedItem;

			System.Diagnostics.Debug.WriteLine("DocProject property changed: " + e.ChangedItem.Label);

			project.IsSaved = false;

			if (item == grid.SelectedGridItem)
				SynchronizeResetItem(item);
		}

		private void resetToolStripMenuItem_Click(object sender, EventArgs e)
		{
			grid.ResetSelectedProperty();
		}

		private void descriptionToolStripMenuItem_Click(object sender, EventArgs e)
		{
			grid.HelpVisible = descriptionToolStripMenuItem.Checked;
		}
		#endregion
	}
}
